package com.cctc.juc.demo.Bitc.Tmp.ADemo;

import java.util.concurrent.Phaser;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

public class IPhaserDemo {

    // 效果 8： A、B、C 分成 3 个阶段，依次向下执行。

    private static Phaser phaser = new Phaser(3) {
        @Override
        protected boolean onAdvance(int phase, int registeredParties) {
            return phase == 3 || registeredParties == 0;
        }
    };

    public static void main(String[] args) {
        for (char ch = 'A'; ch <= 'C'; ch++) {
            final String threadName = String.valueOf(ch);
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + " 线程，正在运行...");
                try {
                    Thread.sleep(ThreadLocalRandom.current().nextInt(3000));
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

                System.out.println(Thread.currentThread().getName() + " 线程，已到达 [phase 0]...");
                phaser.arriveAndAwaitAdvance();

                System.out.println(Thread.currentThread().getName() + " 线程，正在运行...");
                try {
                    Thread.sleep(ThreadLocalRandom.current().nextInt(3000));
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

                System.out.println(Thread.currentThread().getName() + " 线程，已到达 [phase 1]...");
                phaser.arriveAndAwaitAdvance();

                System.out.println(Thread.currentThread().getName() + " 线程，正在运行...");
                try {
                    Thread.sleep(ThreadLocalRandom.current().nextInt(3000));
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

                System.out.println(Thread.currentThread().getName() + " 线程，运行结束！！！");
            }, threadName).start();
        }
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

}
